﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MyTRCP.Common;
using MyTRCP.Common.Services;
using System.Windows;

namespace MyTRCP.Client
{
    public class MyWpfStarter : IHostedService
    {
        private readonly ILogger<MyWpfStarter> _logger;
        private readonly IServiceProvider _serviceProvider;
        private readonly IHostApplicationLifetime _hal;
        private Thread? _wpfThread;
        private volatile App? _app;
        private readonly ILogger<MainWindow> _logger_mw;
        private readonly IConfigService _ics;
        private readonly DevCtrlLinkService _dcls;
        private readonly DevAudioLinkService _dals;
        private readonly MyProtocolClientSideService _mpcss;
        private readonly DevCmdService _dcs;
        private readonly AudioAvgLouldnessComputeService _aalcs;
        private readonly AudioRecordService _ars;
        private readonly AudioPlayService _aps;
        private readonly AudioConvertService _acs;
        private readonly RemoteAudioRouteService _rars;
        private readonly MyAudioRouteService _myars;
        private readonly MicAudioRouteService _mars;
        private readonly MicRecordService _mrs;
        private readonly List<IHostedService> _srvs;

        public MyWpfStarter(ILogger<MyWpfStarter> logger, IServiceProvider isp)
        {
            logger.LogDebug($"MyWpfStarter creating...");
            _srvs = new List<IHostedService>();
            _logger = logger;
            _serviceProvider = isp;

            _mpcss = _serviceProvider.GetRequiredService<MyProtocolClientSideService>();
            _dcls = _serviceProvider.GetRequiredService<DevCtrlLinkService>();
            _dals = _serviceProvider.GetRequiredService<DevAudioLinkService>();
            _acs = _serviceProvider.GetRequiredService<AudioConvertService>();
            _aps = _serviceProvider.GetRequiredService<AudioPlayService>();
            _mrs = _serviceProvider.GetRequiredService<MicRecordService>();
            _rars = _serviceProvider.GetRequiredService<RemoteAudioRouteService>();
            _myars = _serviceProvider.GetRequiredService<MyAudioRouteService>();
            _mars = _serviceProvider.GetRequiredService<MicAudioRouteService>();
            _aalcs = _serviceProvider.GetRequiredService<AudioAvgLouldnessComputeService>();
            _ars = _serviceProvider.GetRequiredService<AudioRecordService>();
            _dcs = _serviceProvider.GetRequiredService<DevCmdService>();

            _srvs.AddRange([_mpcss, _dcls, _dals, _acs, _aps, _mrs, _rars, _myars, _mars, _aalcs, _ars, _dcs]);

            _hal = _serviceProvider.GetRequiredService<IHostApplicationLifetime>();
            _logger_mw = _serviceProvider.GetRequiredService<ILogger<MainWindow>>();
            _ics = _serviceProvider.GetRequiredService<IConfigService>();
        }
        private void StartWpf()
        {
            if (_ics is ClientConfigService ccs)
            {
                _app = new App();
                MainWindow window = new MainWindow(_logger_mw, ccs, _dcls, _dals, _mpcss, _dcs, _aalcs, _ars, _aps, _mrs);
                _app.Startup += _app_Startup;
                _app.Exit += App_Exit;
                _app.Run(window);
            }
            else
            {
                _logger.LogError("服务配置错误：未配置ClientConfigService，无法创建客户端窗口。请检查配置。");
            }
        }

        private void _app_Startup(object sender, StartupEventArgs e)
        {
            if (_ics is ClientConfigService ccs && ccs.ClientMode == ClientModeEnum.Remote && !_mpcss.Open())
            {
                _hal.StopApplication();
            }
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            foreach (IHostedService ihs in _srvs)
            {
                try
                {
                    _logger.LogDebug($"准备启动{ihs.GetType()}");
                    await ihs.StartAsync(cancellationToken);
                    _logger.LogDebug($"{ihs.GetType()}已启动");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "服务启动失败");
                }
            }

            _wpfThread = new Thread(StartWpf);
            _wpfThread.SetApartmentState(ApartmentState.STA);
            _wpfThread.Start();
        }

        private void App_Exit(object sender, ExitEventArgs e)
        {
            _mpcss.Close();
            _hal.StopApplication();
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            _app?.Dispatcher.InvokeShutdown();

            foreach (IHostedService ihs in _srvs)
            {
                try
                {
                    _logger.LogDebug($"准备结束{ihs.GetType()}");
                    await ihs.StopAsync(cancellationToken);
                    _logger.LogDebug($"{ihs.GetType()}已结束");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "服务结束失败");
                }
            }
        }
    }
}
